package DyingBaby.cli;

import DyingBaby.backend.catalog.Catalog;
import DyingBaby.backend.exec.Executor;
import DyingBaby.backend.common.QueryResult;
import DyingBaby.backend.common.PageCacheManager;
import DyingBaby.backend.common.InteractiveCacheConfig;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Map;

public class Repl {
    public static void main(String[] args) throws Exception {
        System.out.println("An interactive environment for a DB named D(ying)B(aby). ");
        System.out.println("Type '.exit' to quit ~");
        Catalog catalog = new Catalog();
        Executor executor = new Executor(catalog);
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        while (true) {
            System.out.print("D(ying)B(aby)> ");
            String line = br.readLine();
            if (line == null) break;
            line = line.trim();
            if (line.isEmpty()) continue;
            if (".exit".equalsIgnoreCase(line)) break;
            try {
                // 在SQL执行前询问是否查看缓存统计信息
                boolean showStats = askForCacheStats();
                InteractiveCacheConfig.setUserChoice(showStats);
                
                //打印执行耗时
                QueryResult result = executor.execute(line);
                Object res = result.data;
                if (res instanceof String) {
                    System.out.println(res);
                } else if (res instanceof List) {
                    @SuppressWarnings("unchecked")
                    List<Map<String,Object>> rows = (List<Map<String,Object>>) res;
                    for (Map<String,Object> row : rows) {
                        System.out.println(row);
                    }
                    System.out.println("(" + rows.size() + " row(s))");
                } else if (res == null) {
                    System.out.println("OK");
                } else {
                    System.out.println(String.valueOf(res));
                }
                System.out.println("[Plan] " + result.planType + ", [Time] " + result.elapsedMillis + " ms");
                
                // SQL执行完成后，如果用户选择查看，则显示缓存统计信息
                if (showStats) {
                    showCacheStats();
                }
                
            } catch (Exception e) {
                System.out.println("ERROR: " + e.getMessage());
                if (e.getCause() != null) {
                    System.out.println("CAUSE: " + e.getCause().toString());
                    for (StackTraceElement ste : e.getCause().getStackTrace()) {
                        System.out.println("  at " + ste);
                    }
                } else {
                    for (StackTraceElement ste : e.getStackTrace()) {
                        System.out.println("  at " + ste);
                    }
                }
            }
        }
        System.out.println("Bye~See you next time~");
    }
    
    /**
     * 询问用户是否查看缓存统计信息
     * @return true表示查看，false表示不查看
     */
    private static boolean askForCacheStats() {
        System.out.println("\n是否查看缓存统计信息？");
        System.out.println("1. 查看");
        System.out.println("2. 不查看");
        System.out.print("请选择 (1/2): ");
        
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            String input = br.readLine().trim();
            
            if ("1".equals(input)) {
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            // 如果读取输入失败，默认不显示
            return false;
        }
    }
    
    /**
     * 显示缓存统计信息
     */
    private static void showCacheStats() {
        Map<String, DyingBaby.backend.dm.pageCache.PageCacheImpl> caches = PageCacheManager.getAllCaches();
        if (caches.isEmpty()) {
            return; // 没有活动的缓存，不显示
        }
        
        System.out.println("\n=== 缓存统计信息 ===");
        for (Map.Entry<String, DyingBaby.backend.dm.pageCache.PageCacheImpl> entry : caches.entrySet()) {
            String tableName = entry.getKey();
            DyingBaby.backend.dm.pageCache.PageCacheImpl cache = entry.getValue();
            System.out.println("\n表: " + tableName);
            System.out.println(cache.getCacheStats());
            System.out.println("当前页面总数: " + cache.getPageNumber());
            System.out.println("缓存利用率: " + cache.getCacheUtilizationString());
        }
        System.out.println("========================");
    }
} 